package com.sanley.piss.web.manager.shiro;

import com.gitee.dreamkaylee.shiro.authc.exception.ExpiredAccountException;
import com.gitee.dreamkaylee.shiro.authz.repository.AbstractShiroPrincipalRepository;
import com.gitee.dreamkaylee.shiro.constant.UserStatus;
import com.google.common.collect.Sets;
import com.sanley.piss.mapper.MenuMapper;
import com.sanley.piss.mapper.UserMapper;
import com.sanley.piss.model.po.Role;
import com.sanley.piss.model.vo.LoginUser;
import com.sanley.piss.model.vo.UserVO;
import org.apache.shiro.authc.*;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author limk
 * @date 2020/12/16 16:42
 */
@Component
public class SinopecShiroPrincipalRepositoryImpl extends AbstractShiroPrincipalRepository {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;

    @Override
    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        if (!StringUtils.hasText(usernamePasswordToken.getUsername()) || usernamePasswordToken.getPassword() == null) {
            throw new UnknownAccountException("Username or password is required.");
        }

        UserVO user = userMapper.getUserByUsername(usernamePasswordToken.getUsername());
        if (user == null) {
            throw new UnknownAccountException("Username or password is incorrect, please re-enter.");
        }

        if (user.getState().equals(UserStatus.LOCKED.getCode())) {
            throw new LockedAccountException("Account is locked.");
        }
        if (user.getState().equals(UserStatus.DISABLE.getCode())) {
            throw new DisabledAccountException("Account is disabled.");
        }
        if (user.getState().equals(UserStatus.EXPIRED.getCode())) {
            throw new ExpiredAccountException("Account is expired.");
        }

        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(user.getId().toString());
        loginUser.setUsername(user.getUsername());
        loginUser.setPassword(user.getPassword());
        loginUser.setSalt(user.getSalt());
        loginUser.setOrgName(user.getOrganization().getOrgName());
        loginUser.setOrganizations(Sets.newHashSet(String.valueOf(user.getDeptId())));
        loginUser.setRoles(user.getRoles().stream().map(Role::getCode).collect(Collectors.toSet()));

        /**
         * 填入权限
         */
        Set<String> code = menuMapper.selectCodeByUserId(user.getId());
        // 权限，自己根据需求查
        loginUser.setPerms(code);

        //        shiroPrincipal.setProfile(); // 其他用户信息，根据需求查
        //        shiroPrincipal.setInitial(user.getInitial());

        return new SimpleAuthenticationInfo(loginUser, user.getPassword(), ByteSource.Util.bytes(loginUser.getSalt()), "login");
    }

    @Override
    public void doLock(Object principal) {

    }

}
